VRC Light Volumesの実装について
lilToonやFilamented Standard for UnityがVRCLVに対応したが、そもそもVRCLV対応ってなんだ?となり、VRCLVの実装自体を調べてみたのでメモ。
端的に言うと、対応させたいshaderに対してLightVolumes.cgincをincludeして必要な関数や変数を取り込み、それらを使ってfragment shaderとかでのライティングをしてあげればVRCLV対応になるみたい。(参考)
以下はLightVolumeManger.csの抜粋。VRCLVの実装的には、ライティングに必要な情報をsetGlobalVectorArray()などを使ってグローバルに設定し、それらをVRCLV対応shaderで読み込むことでVRCLVでのライティングを可能にしてる模様。
code:LightVolumeManager.cs
...
private int lightVolumeInvLocalEdgeSmoothID;
private int lightVolumeColorID;
private int lightVolumeCountID;
...
// Light Volumes
lightVolumeInvLocalEdgeSmoothID = VRCShader.PropertyToID("_UdonLightVolumeInvLocalEdgeSmooth");
lightVolumeInvWorldMatrixID = VRCShader.PropertyToID("_UdonLightVolumeInvWorldMatrix");
lightVolumeColorID = VRCShader.PropertyToID("_UdonLightVolumeColor");
lightVolumeCountID = VRCShader.PropertyToID("_UdonLightVolumeCount");
...
// Light Volumes
VRCShader.SetGlobalVectorArray(lightVolumeInvLocalEdgeSmoothID, new Vector432);
VRCShader.SetGlobalVectorArray(lightVolumeColorID, new Vector432);
VRCShader.SetGlobalMatrixArray(lightVolumeInvWorldMatrixID, new Matrix4x432);
VRCShader.SetGlobalVectorArray(lightVolumeRotationQuaternionID, new Vector432);
...
肝心のベイクしたライティング情報は、$ \ell=1までの球面調和関数の係数を保存する3つの3Dテクスチャ保存された後、それらをアトラス化したものを使っているよう。Light Volume Atlasってやつ。ちなみにそのテクスチャ画像は_UdonLightVolumeColorという名前で扱われているみたい。
詳しくはVRC Light Volumesで擬似リアルタイムライティングしたい!を参照。
ここまでわかると、改造VRCLVがちょっと理解できる。
See also: ShaderLVExampleを通して改造VRCLVを知る